package com.ytd.common.util;

import android.util.Log;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class LogUtil {
    private static final String LOG_FORMAT = "[%s]%-22s[%s]%-20s[%s]\r\n";
    private static final String LOG_FORMAT_2 = "[%s]";
    private static final String LEVEL_D = "D";
    private static final String LEVEL_E = "E";
    private static final String LEVEL_I = "i";
    private static final String LEVEL_V = "V";
    private static final String LEVEL_W = "W";

    private static final String TAG = "com.ytd";

    private static boolean LOG_ENABLE = true;
    private static boolean LOG_SAVE_FILE = true;
    private static String lastMsg = "";
    private static String lastThreadName = "";

    private static List<String> ignoreTag;
    private static List<String> ignoreMsg;

    static {
        ignoreTag = new ArrayList<>();
        ignoreMsg = new ArrayList<>();

        ignoreTag.add("Socket");

        ignoreMsg.add("processRequest:heartBeat");
        ignoreMsg.add("handleEvent:heartBeat");
        ignoreMsg.add("processPush  default");
    }

    public static File InitLog() {
        File logFile = new File(FileUtils.LOG_PATH + "/" + FormatUtil.getDayFormat(new Date()) + ".debug");
        if (!logFile.getParentFile().exists()) {
            logFile.getParentFile().mkdirs();
        }
        if (!logFile.exists()) {
            try {
                logFile.createNewFile();
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        return logFile;
    }

    public static void deleteLOG() {
        ThreadUtil.execute(() -> {
            Date today = new Date(System.currentTimeMillis());
            Date oldday;
            File file = new File(FileUtils.LOG_PATH);

            File[] files = file.listFiles();

            if (files == null) {
                return;
            }

            for (int i = 0; i < files.length; i++) {
                try {
                    oldday = FormatUtil.dayFormat.parse(
                        files[i].getAbsolutePath().substring(files[i].getAbsolutePath().lastIndexOf("/") + 1)
                            .substring(0, 8));
                    if (((today.getTime() - oldday.getTime()) / 1000 / 60 / 60 / 24) > 30) {
                        new File(files[i].getAbsolutePath()).delete();
                        LogUtil.d("log File  " + files[i].getAbsolutePath() + "  delete");
                    }
                } catch (ParseException e) {
                    e.printStackTrace();
                }
            }
        });
    }

    private static void addLog(String level, String tag, String msg) {
        if (!LOG_SAVE_FILE || ignoreTag.contains(tag) || ignoreMsg.contains(msg)) {
            return;
        }
        String threadName = String.format(LOG_FORMAT_2, Thread.currentThread().getName());
        if (lastMsg != null && lastMsg.equals(msg) &&
            (lastThreadName != null && lastThreadName.equals(threadName))) {
            return;
        }
        lastMsg = msg;
        lastThreadName = threadName;
        ThreadUtil.executeFile(() -> {
            try {
                BufferedWriter bw = new BufferedWriter(new FileWriter(InitLog(), true));
                bw.write(String.format(LOG_FORMAT, FormatUtil.getLogTimeFormat(new Date()), threadName, level,
                    String.format(LOG_FORMAT_2, tag), msg));
                bw.flush();
                bw.flush();
                bw.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        });
    }

    public static void crashHandlerLog(String msg) {
        Log.e(TAG, msg);
        String threadName = String.format(LOG_FORMAT_2, Thread.currentThread().getName());
        try {
            BufferedWriter bw = new BufferedWriter(new FileWriter(InitLog(), true));
            bw.write(String.format(LOG_FORMAT, FormatUtil.getLogTimeFormat(new Date()), threadName, LEVEL_E,
                String.format(LOG_FORMAT_2, "CrashHandler"), msg));
            bw.flush();
            bw.flush();
            bw.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 设置是否显示Log
     *
     * @param enable true-显示 false-不显示
     */
    public static void setLogEnable(boolean enable) {
        LOG_ENABLE = enable;
    }

    /**
     * verbose log
     *
     * @param msg log msg
     */
    public static void v(String msg) {
        if (LOG_ENABLE) {
            Log.v(TAG, msg);
        }
        addLog(LEVEL_V, TAG, msg);
    }

    /**
     * verbose log
     *
     * @param tag tag
     * @param msg log msg
     */
    public static void v(String tag, String msg) {
        if (LOG_ENABLE) {
            Log.v(tag, msg);
        }
        addLog(LEVEL_V, tag, msg);
    }

    /**
     * debug log
     *
     * @param msg log msg
     */
    public static void d(String msg) {
        if (LOG_ENABLE) {
            Log.d(TAG, msg);
        }
        addLog(LEVEL_D, TAG, msg);
    }

    /**
     * debug log
     *
     * @param tag tag
     * @param msg log msg
     */
    public static void d(String tag, String msg) {
        if (LOG_ENABLE) {
            Log.d(tag, msg);
        }
        addLog(LEVEL_D, tag, msg);
    }

    /**
     * info log
     *
     * @param msg log msg
     */
    public static void i(String msg) {
        if (LOG_ENABLE) {
            Log.i(TAG, msg);
        }
        addLog(LEVEL_I, TAG, msg);
    }

    /**
     * info log
     *
     * @param tag tag
     * @param msg log msg
     */
    public static void i(String tag, String msg) {
        if (LOG_ENABLE) {
            Log.i(tag, msg);
        }
        addLog(LEVEL_I, tag, msg);
    }

    /**
     * warning log
     *
     * @param msg log msg
     */
    public static void w(String msg) {
        if (LOG_ENABLE) {
            Log.w(TAG, msg);
        }
        addLog(LEVEL_W, TAG, msg);
    }

    /**
     * warning log
     *
     * @param msg log msg
     * @param e exception
     */
    public static void w(String msg, Exception e) {
        if (LOG_ENABLE) {
            Log.w(TAG, msg, e);
        }
        addLog(LEVEL_W, TAG, msg + "---" + Log.getStackTraceString(e));
    }

    /**
     * warning log
     *
     * @param tag tag
     * @param msg log msg
     */
    public static void w(String tag, String msg) {
        if (LOG_ENABLE) {
            Log.w(tag, msg);
        }
        addLog(LEVEL_W, tag, msg);
    }

    /**
     * warning log
     *
     * @param tag tag
     * @param msg log msg
     * @param e exception
     */
    public static void w(String tag, String msg, Exception e) {
        if (LOG_ENABLE) {
            Log.w(tag, msg, e);
        }
        addLog(LEVEL_W, tag, msg + "---" + Log.getStackTraceString(e));
    }

    /**
     * error log
     *
     * @param msg log msg
     */
    public static void e(String msg) {
        if (LOG_ENABLE) {
            Log.e(TAG, msg);
        }
        addLog(LEVEL_E, TAG, msg);
    }

    /**
     * error log
     *
     * @param msg log msg
     * @param e exception
     */
    public static void e(String msg, Exception e) {
        if (LOG_ENABLE) {
            Log.e(TAG, msg, e);
        }
        addLog(LEVEL_E, TAG, msg + "---" + Log.getStackTraceString(e));
    }

    /**
     * error log
     *
     * @param tag tag
     * @param msg msg
     */
    public static void e(String tag, String msg) {
        if (LOG_ENABLE) {
            Log.e(tag, msg);
        }
        addLog(LEVEL_E, tag, msg);
    }

    /**
     * error log
     *
     * @param tag tag
     * @param msg log msg
     * @param e exception
     */
    public static void e(String tag, String msg, Throwable e) {
        if (LOG_ENABLE) {
            Log.e(tag, msg, e);
        }
        addLog(LEVEL_E, tag, msg + "---" + Log.getStackTraceString(e));
    }
}
